/*
 * PlanComplex.java
 * 
 * Copyright 2004 Christoph Csallner and Yannis Smaragdakis.
 */
package edu.gatech.cc.cnc.plans.stmt;

import static edu.gatech.cc.jcrasher.Assertions.check;
import static edu.gatech.cc.jcrasher.Assertions.notNull;
import edu.gatech.cc.jcrasher.plans.expr.Expression;
import edu.gatech.cc.jcrasher.plans.expr.Variable;
import edu.gatech.cc.jcrasher.plans.expr.literals.PrimitiveLiteral;
import edu.gatech.cc.jcrasher.plans.stmt.Block;
import edu.gatech.cc.jcrasher.plans.stmt.BlockStatement;
import edu.gatech.cc.jcrasher.plans.stmt.LocalVariableDeclarationStatement;

/**
 * Sequence of statements setting the fields of a complex variable.
 * 
 * @param <T> type of the created complex variable.
 * 
 * @author csallner@gatech.edu (Christoph Csallner)
 */
public class ComplexVariableCreatingBlockStatementSequence<T> extends ReferenceVariableCreatingBlockStatementSequence<T> {
	
	/**
	 * Constructor: C id = newInstance(); set(id, p1); set(id, p2).
	 * 
	 * Set public fields for which we have plans.
	 */	
	public ComplexVariableCreatingBlockStatementSequence(
      Class<?> testeeType,
      Block<?> enclosingBlock,
      Variable<T> variable,
      Expression<? extends T> defaultPlan,
      BlockStatement<?>[] fieldPlans,
      String[] fieldNames)
  {
		super(enclosingBlock, variable, fieldPlans);
		notNull(defaultPlan); 
    check(fieldPlans.length==fieldNames.length);
		
		/* A a = <JCrasher-plan>; */
		super.statements.add(new LocalVariableDeclarationStatement<T>(name, defaultPlan));
		
		/* A.field.set(a, p) */
		for (int i=0; i<fieldPlans.length; i++) {
      
			String set = variable.getReturnType().getName() +".class.getDeclaredField(\""
				+ fieldNames[i] +"\")" +".set(" +variable +", ";
      
			if (fieldPlans[i] instanceof PrimitiveLiteral) {
        PrimitiveLiteral<?> literal = (PrimitiveLiteral) fieldPlans[i];
				set += "new ";
				if (literal.getReturnType().equals(Integer.TYPE)) {set += "Integer";}
				if (literal.getReturnType().equals(Long.TYPE)) {set += "Long";}
				if (literal.getReturnType().equals(Short.TYPE)) {set += "Short";}
				if (literal.getReturnType().equals(Byte.TYPE)) {set += "Byte";}
				if (literal.getReturnType().equals(Character.TYPE)) {set += "Character";}
				if (literal.getReturnType().equals(Boolean.TYPE)) {set += "Boolean";}
				if (literal.getReturnType().equals(Double.TYPE)) {set += "Double";}
				if (literal.getReturnType().equals(Float.TYPE)) {set += "Float";}
				set += " (" +localNames[i] +"));";
			}
			else {
				set += localNames[i]+");";
			}
			super.statements.add(new RawStatement(set));
		}
	}

}
